"""
继承：从已有的类创建新类的过程，提供继承信息的称为父类，得到继承信息的称为子类。
多态：不同的对象接收到相同的消息会表现出不同的行为。
实现多态最关键的步骤是，子类在继承父类过程中，重写父类方法，不同的子类给出不同的实现版本。
工资结算系统：部门经理固定月薪15000元，程序员计时支付工资，每小时200元，
销售员底薪1800元加上销售额提成5%，根据录入的员工信息，为每个员工结算月薪。
"""
from abc import abstractmethod, ABCMeta


# 抽象类（不能创建对象的类，专门用于继承）
class Employee(metaclass=ABCMeta):
    """员工"""

    def __init__(self, name):
        self.name = name

    # 抽象方法（留给子类去实现的方法）
    @abstractmethod
    def get_salary(self):
        pass


class Manager(Employee):
    """部门经理"""

    def get_salary(self):
        return 15000


class Programmer(Employee):
    """程序员"""

    def __init__(self, name):
        self.working_hour = 0
        super().__init__(name)

    def get_salary(self):
        return 200 * self.working_hour


class Salesman(Employee):
    """销售员"""

    def __init__(self, name):
        self.sales = 0
        super().__init__(name)

    def get_salary(self):
        return 1800 + self.sales * 0.05


def main():
    emps = [
        Manager('曹操'), Programmer('荀彧'), Programmer('郭嘉'),
        Salesman('典韦'), Salesman('曹仁'), Programmer('张辽')
    ]
    for emp in emps:
        if isinstance(emp, Programmer):
            emp.working_hour = int(input(f'请输入{emp.name}本月工作时间: '))
        elif isinstance(emp, Salesman):
            emp.sales = float(input(f'请输入{emp.name}本月销售额: '))
        print(f'{emp.name}本月工资为: {emp.get_salary():.2f}元')


if __name__ == '__main__':
    main()
